package com.fy.fyai.service.downloaddecorator.component;

import com.fy.fyai.common.utils.CosFullPathDownloadUtil;
import com.fy.fyai.service.downloaddecorator.DownloadComponent;
import com.fy.fyai.service.downloaddecorator.service.FileMetadataService;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.COSObject;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author fwq
 * @description 基础下载组件（装饰器模式的具体组件）
 * @date 2025-11-03 20:05
 */
@Slf4j
@Component
public class BaseDownload implements DownloadComponent {
    
    @Resource
    private COSClient cosClient;
    
    @Resource
    private FileMetadataService fileMetadataService;
    
    @Resource
    private CosFullPathDownloadUtil cosFullPathDownloadUtil;
    
    /**
     * 本地临时文件目录
     */
    private static final String TEMP_DIR = "F:/COS下载文件/temp/";

    /**
     * 基础下载实现：从数据库获取COS key -> 下载到本地 -> 返回文件流
     * 
     * @param fileId 文件ID
     * @return 文件信息（包含输入流）
     */
    @Override
    public FileInfo downloadFile(String fileId) {
        log.info("基础下载：开始下载文件 {}", fileId);
        
        try {
            // 1. 从数据库获取COS key和文件名
            String cosKey = fileMetadataService.getCosKeyByFileId(fileId);
            String fileName = fileMetadataService.getFileNameByFileId(fileId);
            
            log.info("基础下载：文件ID {} 对应的COS key: {}", fileId, cosKey);
            
            // 2. 从COS下载文件到本地临时目录
            String localFilePath = downloadFromCosToLocal(cosKey, fileId);
            
            // 3. 读取本地文件并返回流
            File localFile = new File(localFilePath);
            FileInputStream fileInputStream = new FileInputStream(localFile);
            
            // 4. 获取文件大小和内容类型
            long fileSize = localFile.length();
            String contentType = Files.probeContentType(localFile.toPath());
            if (contentType == null) {
                contentType = "application/octet-stream";
            }
            
            log.info("基础下载：文件 {} 下载完成，大小: {} bytes", fileId, fileSize);
            
            return new FileInfo(fileInputStream, fileName, fileSize, contentType);
            
        } catch (Exception e) {
            log.error("基础下载：文件 {} 下载失败", fileId, e);
            throw new RuntimeException("文件下载失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 从COS下载文件到本地临时目录
     * 
     * @param cosKey COS存储桶的key
     * @param fileId 文件ID（用于生成临时文件名）
     * @return 本地文件路径
     */
    private String downloadFromCosToLocal(String cosKey, String fileId) throws IOException {
        // 创建临时目录
        Path tempDirPath = Paths.get(TEMP_DIR);
        if (!Files.exists(tempDirPath)) {
            Files.createDirectories(tempDirPath);
        }
        
        // 生成临时文件路径
        String tempFileName = fileId + "_" + System.currentTimeMillis() + ".tmp";
        String localFilePath = TEMP_DIR + tempFileName;
        
        // 解析COS key获取bucket（这里简化处理，实际应该从配置或数据库获取）
        // TODO: 后续从数据库或配置获取bucket和region
        String bucketName = "fy-1330848370"; // 示例bucket名称
        
        log.info("基础下载：从COS下载文件，bucket: {}, key: {}", bucketName, cosKey);
        
        // 从COS下载到本地
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, cosKey);
        
        try (COSObject cosObject = cosClient.getObject(getObjectRequest);
             InputStream cosIn = cosObject.getObjectContent();
             BufferedOutputStream localOut = new BufferedOutputStream(new FileOutputStream(localFilePath))) {
            
            byte[] buffer = new byte[8192]; // 8KB缓冲区
            int bytesRead;
            while ((bytesRead = cosIn.read(buffer)) != -1) {
                localOut.write(buffer, 0, bytesRead);
            }
            localOut.flush();
        }
        
        log.info("基础下载：文件已下载到本地: {}", localFilePath);
        return localFilePath;
    }
}